"""
主题: 为类和静态方法提供装饰器
问题: 你想使用一个装饰器去包装函数，但是希望返回一个可调用的实例。 你需要让你的装饰器可以同时工作在类定义的内部和外部。
提示 : 
"""

import time
from functools import wraps

# A simple decorator
def timethis(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        r = func(*args, **kwargs)
        end = time.time()
        print(end-start)
        return r
    return wrapper

# Class illustrating application of the decorator to different kinds of methods
class Spam:
    @timethis
    def instance_method(self, n):
        print(self, n)
        while n > 0:
            n -= 1

    @classmethod
    @timethis
    def class_method(cls, n):
        print(cls, n)
        while n > 0:
            n -= 1

    @staticmethod
    @timethis
    def static_method(n):
        print(n)
        while n > 0:
            n -= 1

from abc import ABCMeta, abstractmethod
class A(metaclass=ABCMeta):
    '''两者的顺序是有讲究的，如果你调换它们的顺序就会出错'''
    #@abstractmethod
    @classmethod
    @abstractmethod
    def method(cls):
        print("method")

def recipe1():
    s = Spam()
    print(f"{s.instance_method(1000000) = }")
    print(f"{Spam.class_method(1000000) = }")
    print(f"{Spam.static_method(1000000) = }")

def recipe2():
    print(f"{A.method() = }")

def main():
    print('recipe1'.center(20, '*'))
    recipe1()
    print('recipe2'.center(20, '*'))
    recipe2()

if __name__ == '__main__':
    main()   